﻿namespace DOMercury.Managers
{
    using DOMercury.Controls;
    using DOMercury.Interfaces;
    using DOMercury.Items;
    using DOMercuryInterfaces.Items;
    using ManagedWinapi.Windows;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    using System.Xml;

    internal static class AutoCompleteManager
    {
        private static List<IItemContainer> currentIndex;
        public static List<string> FileExtensionsToIgnore;
        private static List<TextItem> history;
        private static List<IItemContainer> index;
        private static IndexStack istack;
        private static ItemStack itstack;
        private static int MATCHLIM = ConfigurationManager.MaxResults;
        private static AutoCompleteStringCollection Params;
        public static bool PauseRefresh = false;
        private static Hashtable PriorityHash;
        private static bool reindex = false;
        private static bool SearchOn;
        private static bool SMARTSEARCH = ConfigurationManager.SmartSearch;
        private static List<StartMenuItem> smlist;
        private static StringStack sstack;
        private static Dictionary<string, List<IItemContainer>> cachedIndexResults;
        private static Dictionary<string, int> cachedIndexResultIndices;
        private static bool cachedIndexesUseSmartSearch;


        private static void AddToHash(IItemContainer item)
        {
            int hash = GetHash(item);
            if (!PriorityHash.Contains(hash))
            {
                PriorityHash.Add(hash, item.Priority);
            }
            else
            {
                PriorityHash[hash] = item.Priority;
            }
        }

        public static void AddToItemHistory(TextItem item)
        {
            if ((((item.Text.ToLower() != "current window") && (item.Text.Length >= 2)) && !history.Contains(item)) && ((item.Text[1] != ':') || (item.Text.Length >= 4)))
            {
                history.Add(item);
                Save();
            }
        }

        public static void AddToParamHistory(string param)
        {
            if (((param.Length >= 2) && !Params.Contains(param)) && ((param[1] != ':') || (param.Length >= 4)))
            {
                Params.Add(param);
                Save();
            }
        }

        private static void BuildIcons(bool plugs)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(AutoCompleteManager.bwIcon_DoWork);
            if (plugs)
            {
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(AutoCompleteManager.bw_RunWorkerPCompleted);
            }
            else
            {
                PullPriorities();
                SortIndex();
            }
            worker.RunWorkerAsync();
        }

        private static void BuildIndex(bool Rebuild)
        {
            if (Rebuild)
            {
                SavePriorities();
            }
            List<IItemContainer> list = new List<IItemContainer>();
            BuildSMList();
            foreach (IItem item in smlist)
            {
                list.Add(new IItemContainer(item));
            }
            list.Add(new IItemContainer(new CurrentWindowItem(), 0x7fffffff));
            list.Add(new IItemContainer(new RefreshIndexItem()));
            list.Add(new IItemContainer(new ScreenSaverItem(), 0x7fffffff));
            list.Add(new IItemContainer(new MyComputerItem(), 0x7fffffff));
            list.Add(new IItemContainer(new DeskTopItem(), 0x7fffffff));
            list.Add(new IItemContainer(new OptionsItem(), 0x7fffffff));
            list.Add(new IItemContainer(new GoogleItem(), 0x7fffffff));
            list.Add(new IItemContainer(new RefreshItem()));
            list.Add(new IItemContainer(new ExitItem(), 0x7fffffff));
            foreach (IItem item2 in history)
            {
                list.Add(new IItemContainer(item2));
            }
            list.Sort();
            if (currentIndex == index)
            {
                index = list;
                cachedIndexResults.Clear();
                cachedIndexResultIndices.Clear();
                istack.ResetBase(index);
                currentIndex = index;
            }
            else
            {
                index = list;
                cachedIndexResults.Clear();
                cachedIndexResultIndices.Clear();
                istack.ResetBase(index);
            }
            BuildIcons(true);
        }

        private static void BuildSMList()
        {
            DirectoryInfo info;
            List<StartMenuItem> list = new List<StartMenuItem>();
            if (Environment.OSVersion.Version.Major == 6)
            {
                info = new DirectoryInfo(Environment.GetEnvironmentVariable("ALLUSERSPROFILE") + @"\Microsoft\Windows\Start Menu");
            }
            else
            {
                info = new DirectoryInfo(Environment.GetEnvironmentVariable("ALLUSERSPROFILE") + @"\Start Menu");
            }
            foreach (FileInfo info2 in info.GetFiles("*.lnk", SearchOption.AllDirectories))
            {
                list.Add(new StartMenuItem(info2.FullName, Path.GetFileNameWithoutExtension(info2.Name)));
            }
            foreach (FileInfo info3 in info.GetFiles("*.url", SearchOption.AllDirectories))
            {
                list.Add(new StartMenuItem(info3.FullName, Path.GetFileNameWithoutExtension(info3.Name)));
            }
            info = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu));
            foreach (FileInfo info4 in info.GetFiles("*.lnk", SearchOption.AllDirectories))
            {
                list.Add(new StartMenuItem(info4.FullName, Path.GetFileNameWithoutExtension(info4.Name)));
            }
            foreach (FileInfo info5 in info.GetFiles("*.url", SearchOption.AllDirectories))
            {
                list.Add(new StartMenuItem(info5.FullName, Path.GetFileNameWithoutExtension(info5.Name)));
            }
            list.Sort();
            smlist = list;
        }

        private static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BuildIndex(true);
        }

        private static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            BuildIcons(false);
        }

        private static void bw_RunWorkerPCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IndexPlugins();
        }

        private static void bwIcon_DoWork(object sender, DoWorkEventArgs e)
        {
            pBuildIcons();
        }

        private static void bwPlugins_DoWork(object sender, DoWorkEventArgs e)
        {
            pIndexPlugins();
        }

        public static void ChangeItemAutoCompleteSource(ref TransparentTextBox cbItem, string type)
        {
            string str;
            if (((str = type) != null) && (str == "folder"))
            {
                if (cbItem.AutoCompleteSource != AutoCompleteSource.FileSystemDirectories)
                {
                    cbItem.AutoCompleteSource = AutoCompleteSource.FileSystemDirectories;
                    cbItem.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    cbItem.SelectionStart = cbItem.Text.Length;
                    cbItem.SelectionLength = 0;
                }
            }
            else if (cbItem.AutoCompleteSource != AutoCompleteSource.None)
            {
                cbItem.AutoCompleteSource = AutoCompleteSource.None;
                cbItem.AutoCompleteMode = AutoCompleteMode.Suggest;
                cbItem.SelectionStart = cbItem.Text.Length;
                cbItem.SelectionLength = 0;
            }
        }

        public static void ChangeParametersAutoCompleteSource(ref TransparentTextBox cbParams, ref ListBox lbParams, string pType, string iType)
        {
            bool flag;
            switch (pType)
            {
                case "Path":
                    lbParams.DataSource = null;
                    cbParams.AutoCompleteSource = AutoCompleteSource.FileSystemDirectories;
                    cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    return;

                case "PathFiles":
                    lbParams.DataSource = null;
                    cbParams.AutoCompleteSource = AutoCompleteSource.FileSystem;
                    cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    return;

                case "URL":
                    lbParams.DataSource = null;
                    cbParams.AutoCompleteSource = AutoCompleteSource.AllUrl;
                    cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    return;

                case "SendTo":
                    cbParams.AutoCompleteSource = AutoCompleteSource.None;
                    cbParams.AutoCompleteMode = AutoCompleteMode.None;
                    return;

                case "OpenWith":
                    cbParams.AutoCompleteSource = AutoCompleteSource.None;
                    lbParams.DataSource = RegistryManager.GetOpenWithExes(iType);
                    cbParams.AutoCompleteMode = AutoCompleteMode.None;
                    return;

                case "CommandLine":
                    lbParams.DataSource = null;
                    cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    cbParams.AutoCompleteSource = AutoCompleteSource.CustomSource;
                    cbParams.AutoCompleteCustomSource = Params;
                    return;

                case "Unused":
                    lbParams.DataSource = null;
                    cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    cbParams.AutoCompleteSource = AutoCompleteSource.CustomSource;
                    cbParams.AutoCompleteCustomSource = Params;
                    return;

                default:
                    flag = false;
                    foreach (IParametersProvider provider in PluginManager.ParamProviders)
                    {
                        if (pType == provider.ParameterType)
                        {
                            cbParams.AutoCompleteSource = AutoCompleteSource.None;
                            cbParams.AutoCompleteMode = AutoCompleteMode.None;
                            lbParams.DataSource = provider.ParameterDataSource;
                            lbParams.DisplayMember = provider.ParameterDisplayMember;
                            flag = true;
                            break;
                        }
                    }
                    break;
            }
            if (!flag)
            {
                lbParams.DataSource = null;
                cbParams.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                cbParams.AutoCompleteSource = AutoCompleteSource.CustomSource;
                cbParams.AutoCompleteCustomSource = Params;
            }
        }

        public static void ChangePriority(string DisplayName, string DisplayDescription, int Priority)
        {
            IItemContainer container = index.Find(delegate (IItemContainer item) {
                return (item.DisplayDesc == DisplayDescription) && (item.DisplayName == DisplayName);
            });
            if (container != null)
            {
                container.Priority = Priority;
            }
        }

        public static List<IItem> GetAllItems(string text)
        {
            if (currentIndex == index)
            {
                return GetItems(text);
            }
            List<IItem> list = new List<IItem>();
            foreach (IItemContainer container in currentIndex)
            {
                list.Add(container.InnerItem);
            }
            return list;
        }

        private static int GetHash(IItem item)
        {
            StringBuilder builder = new StringBuilder(item.DisplayName);
            builder.Append(item.DisplayDesc);
            builder.Append(item.ItemType);
            return builder.ToString().GetHashCode();
        }

        private static List<string> GetIgnoredFileExtensions()
        {
            List<string> list = new List<string>();
            try
            {
                FileStream stream = new FileStream("FileExtensionsToIgnore.txt", FileMode.Open, FileAccess.Read);
                StreamReader reader = new StreamReader(stream);
                while (!reader.EndOfStream)
                {
                    list.Add(reader.ReadLine().Trim());
                }
            }
            catch
            {
                list.Add(".cache");
                list.Add(".tmp");
                list.Add(".resx");
                list.Add(".ncb");
                list.Add(".obj");
                list.Add(".manifest");
                list.Add(".rc");
                list.Add(".compiled");
                list.Add(".dll");
                list.Add(".resources");
                list.Add(".bin");
                list.Add(".ilk");
                list.Add(".o");
                list.Add(".bak");
                list.Add(".license");
            }
            return list;
        }

        public static List<IItem> GetItems(string text)
        {
            return GetItems(text, SMARTSEARCH);
        }

        private static void GetPriority(IItemContainer it)
        {
            int hash = GetHash(it);
            if (PriorityHash.Contains(hash))
            {
                it.Priority = (int) PriorityHash[hash];
            }
        }

        public static void IncreasePriority(string DisplayName, string DisplayDescription)
        {
            IItemContainer container = index.Find(delegate (IItemContainer item) {
                return (item.DisplayDesc == DisplayDescription) && (item.DisplayName == DisplayName);
            });
            if ((container != null) && (container.Priority != 0x7fffffff))
            {
                container.Priority++;
            }
        }

        private static void IndexPlugins()
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(AutoCompleteManager.bwPlugins_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(AutoCompleteManager.bw_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        public static void ItemTypeCount()
        {
            Dictionary<string, ReferenceInt> dictionary = new Dictionary<string, ReferenceInt>();
            PauseRefresh = true;
            foreach (IItemContainer container in index)
            {
                ReferenceInt num;
                if (dictionary.TryGetValue(container.ItemType, out num))
                {
                    num.Int++;
                    continue;
                }
                dictionary.Add(container.ItemType, new ReferenceInt(1));
            }
            PauseRefresh = false;
        }

        public static void Load()
        {
            FileExtensionsToIgnore = GetIgnoredFileExtensions();
            PriorityHash = new Hashtable();
            LoadPriorities();
            SearchOn = true;
            history = new List<TextItem>();
            Params = new AutoCompleteStringCollection();
            try
            {
                ReadItems(ref history);
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("Could Not find \"AutoComplete.xml\". Unable to load text items history.", "Error, Unable to find AutoComplete.xml", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            catch (Exception)
            {
                MessageBox.Show("\"AutoComplete.xml\" is corrupt or damaged, or possibly in an incorrect format. Unable to load items history.", "Error, Unable to read AutoComplete.xml", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            history.Sort();
            cachedIndexResults = new Dictionary<string, List<IItemContainer>>();
            cachedIndexResultIndices = new Dictionary<string, int>();
            cachedIndexesUseSmartSearch = false;
            index = new List<IItemContainer>();
            istack = new IndexStack(index);
            itstack = new ItemStack();
            sstack = new StringStack();
            BuildIndex(false);
            currentIndex = index;
        }

        private static void LoadPriorities()
        {
            FileStream stream = new FileStream("PersistData.dat", FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
            StreamReader reader = new StreamReader(stream);
            while (!reader.EndOfStream)
            {
                string[] strArray = reader.ReadLine().Split(new char[] { ',' });
                int key = Convert.ToInt32(strArray[0]);
                int num2 = Convert.ToInt32(strArray[1]);
                if (!PriorityHash.ContainsKey(key))
                {
                    PriorityHash.Add(key, num2);
                }
            }
            reader.Close();
            stream.Close();
        }

        private static void pBuildIcons()
        {
            foreach (IItemProvider provider in PluginManager.ItemProviders)
            {
                try
                {
                    foreach (IconPair pair in provider.CustomIcons)
                    {
                        IconManager.AddCustomIcon(pair.Key, pair.Icon);
                    }
                    continue;
                }
                catch
                {
                    continue;
                }
            }
            for (int i = 0; i < index.Count; i++)
            {
                IconManager.AddIcon(index[i].DisplayDesc);
            }
            foreach (Alias alias in AliasManager.AliasList)
            {
                try
                {
                    IconManager.AddCustomIcon(alias.DisplayDesc, Icon.ExtractAssociatedIcon(alias.Path).ToBitmap());
                    continue;
                }
                catch
                {
                    continue;
                }
            }
        }

        public static List<IItemContainer> PGetItems(string text, decimal Number)
        {
            decimal d = 0M;
            StringBuilder builder = new StringBuilder(".*");
            foreach (char ch in text.ToLower().ToCharArray())
            {
                switch (ch)
                {
                    case '.':
                    case '[':
                    case ']':
                    case '(':
                    case ')':
                    case '^':
                    case '$':
                    case '*':
                    case '?':
                    case '+':
                        builder.Append(@"\");
                        break;
                }
                builder.Append(ch.ToString());
                builder.Append(".*");
            }
            Regex regex = new Regex(builder.ToString());
            List<IItemContainer> list = new List<IItemContainer>();
            if (text != "")
            {
                foreach (IItemContainer container in index)
                {
                    if ((d < Number) && regex.IsMatch(container.DisplayName.ToLower()))
                    {
                        list.Add(container);
                        d = d++;
                    }
                }
            }
            return list;
        }

        private static void pIndexPlugins()
        {
            foreach (IItemProvider provider in PluginManager.ItemProviders)
            {
                if (provider.Items == null)
                {
                    continue;
                }
                List<IItemContainer> collection = new List<IItemContainer>();
                foreach (IItem item in provider.Items)
                {
                    if (ShouldAdd(item.DisplayDesc))
                    {
                        collection.Add(new IItemContainer(item));
                    }
                }
                cachedIndexResults.Clear();
                cachedIndexResultIndices.Clear();
                index.AddRange(collection);
            }
        }

        public static void PreviousIndex()
        {
            if (currentIndex != index)
            {
                istack.Pop();
                itstack.Pop();
                sstack.Pop();
                currentIndex = istack.Top;
                SearchOn = istack.TopSearch;
            }
        }

        private static void PullPriorities()
        {
            foreach (IItemContainer container in index)
            {
                GetPriority(container);
            }
        }

        private static void PushPriorities()
        {
            PriorityHash.Clear();
            foreach (IItemContainer container in index)
            {
                AddToHash(container);
            }
        }

        private static List<IItem> GetItems(string text, bool SMARTSEARCH)
        {
            Predicate<SystemWindow> predicate = null;
            List<IItem> list = new List<IItem>();

            Regex txt = null;
            if (SMARTSEARCH)
            {
                StringBuilder builder = new StringBuilder(".*");
                foreach (char ch in text.ToLower().ToCharArray())
                {
                    switch (ch)
                    {
                        case '.':
                        case '[':
                        case ']':
                        case '(':
                        case ')':
                        case '^':
                        case '$':
                        case '*':
                        case '?':
                        case '+':
                            builder.Append(@"\");
                            break;
                    }
                    builder.Append(ch.ToString());
                    builder.Append(".*");
                }
                txt = new Regex(builder.ToString());
            }

            if (!(text != ""))
            {
                if (currentIndex == index)
                {
                    return list;
                }
                List<IItem> list4 = new List<IItem>();
                foreach (IItemContainer container2 in currentIndex)
                {
                    list4.Add(container2.InnerItem);
                }
                return list4;
            }

            if (currentIndex == index)
            {
                SearchOn = true;
                foreach (Alias alias in AliasManager.AliasList)
                {
                    if (text == alias.DisplayName.ToLower())
                    {
                        list.Insert(0, alias);
                        continue;
                    }
                    if ((SMARTSEARCH && txt.IsMatch(alias.DisplayName.ToLower())) || 
                        (!SMARTSEARCH && alias.DisplayName.ToLower().Contains(text)))
                    {
                        list.Add(alias);
                    }
                }
            }

            if (currentIndex == index)
            {
                if (cachedIndexResults.ContainsKey(text) && SMARTSEARCH == cachedIndexesUseSmartSearch)
                {
                    list.AddRange(UnpackContainerList(cachedIndexResults[text]));
                }
                else
                {
                    if (SMARTSEARCH != cachedIndexesUseSmartSearch)
                    {
                        cachedIndexResults.Clear();
                        cachedIndexResultIndices.Clear();
                        cachedIndexesUseSmartSearch = SMARTSEARCH;
                    }

                    bool breakout = false;
                    int i = 0;

                    List<IItemContainer> cacheList = new List<IItemContainer>();

                    string bestCacheKey = "";

                    //find the best appropriate / useful key to help.
                    foreach (string candidateKey in cachedIndexResults.Keys)
                    {
                        if (text.StartsWith(candidateKey))
                            if (candidateKey.Length > bestCacheKey.Length)
                                bestCacheKey = candidateKey;
                    }

                    //if found, do prelim search and fast-forward i 
                    if (bestCacheKey.Length > 0)
                    {
                        List<IItemContainer> previousCacheList = cachedIndexResults[bestCacheKey];

                        for (; i < previousCacheList.Count && !breakout; i++)
                            GetSingleItem(ref cacheList, ref previousCacheList, i, text, txt, ref breakout);

                        i = cachedIndexResultIndices[bestCacheKey];
                        breakout = false; //reset for reuse below
                    }

                    for (; i < currentIndex.Count && !breakout; i++)
                        GetSingleItem(ref cacheList, ref currentIndex, i, text, txt, ref breakout);

                    list.AddRange(UnpackContainerList(cacheList));

                    cachedIndexResults.Add(text, cacheList);
                    cachedIndexResultIndices.Add(text, i);
                }
            }
            else
            {
                for (int i = 0; i < currentIndex.Count; i++)
                {
                    try
                    {
                        list.Add((IItemContainer)(currentIndex[i]).InnerItem);
                    }
                    catch
                    {
                    }
                }
            }

            if (currentIndex == index)
            {
                if (predicate == null)
                {
                    predicate = delegate(SystemWindow c)
                    {
                        if (SMARTSEARCH)
                            return txt.IsMatch(c.Title.ToLower()) && c.Visible;
                        else
                            return c.Title.ToLower().Contains(text) && c.Visible;
                    };
                }
                foreach (SystemWindow window in SystemWindow.FilterToplevelWindows(predicate))
                {
                    list.Add(new SystemWindowItem(window.Title, window.HWnd, window.Process, window.ClassName));
                }
                if (Directory.Exists(PathFinder.FindPath(text)))
                {
                    List<PathItem> items = new List<PathItem>();
                    if (text.EndsWith(":"))
                    {
                        text = text + @"\";
                    }
                    items.Add(new PathItem(PathFinder.FindPath(text), text));
                    list.Add(new ItemsList(items));
                }
                else if (File.Exists(text))
                {
                    List<PathItem> list3 = new List<PathItem>();
                    list3.Add(new PathItem(text, Path.GetFileNameWithoutExtension(text)));
                    list.Add(new ItemsList(list3));
                }
                list.Add(new TextItem(text));
            }
            return list;
        }

        private static void GetSingleItem(ref List<IItemContainer> buildList, ref List<IItemContainer> fromList, int i, string text, Regex txt, ref bool breakout)
        {
            try
            {
                IItemContainer container = fromList[i];
                if (container.DisplayName.ToLower() == text)
                {
                    buildList.Insert(0, container);
                }
                else if ((SMARTSEARCH && txt.IsMatch(container.DisplayName.ToLower())) ||
                    (!SMARTSEARCH && container.DisplayName.ToLower().Contains(text)))
                {
                    buildList.Add(container);
                }
                if (buildList.Count > MATCHLIM)
                {
                    breakout = true;
                }
            }
            catch
            {
            }
        }

        private static List<IItem> UnpackContainerList (List<IItemContainer> list)
        {
            List<IItem> theseItems = new List<IItem>();
            foreach (IItemContainer container in list)
                theseItems.Add(container.InnerItem);
            return theseItems;
        }

        private static string ReadItem(XmlTextReader r)
        {
            return r.GetAttribute("Value");
        }

        private static void ReadItems(ref List<TextItem> items)
        {
            XmlTextReader r = new XmlTextReader(new FileStream(Path.GetDirectoryName(Application.ExecutablePath) + @"\AutoComplete.xml", FileMode.Open, FileAccess.Read));
            while (!r.EOF && (r.Name.Trim().CompareTo("Items") != 0))
            {
                r.Read();
            }
            r.Read();
            while (!r.EOF && (r.Name.Trim().CompareTo("Items") != 0))
            {
                if (r.NodeType == XmlNodeType.EndElement)
                {
                    r.Read();
                }
                else
                {
                    string str = r.Name.Trim();
                    if (str == null)
                    {
                        goto Label_00DC;
                    }
                    if (!(str == "Item"))
                    {
                        if (str == "Param")
                        {
                            goto Label_00BA;
                        }
                        if (str == "")
                        {
                            goto Label_00D3;
                        }
                        goto Label_00DC;
                    }
                    items.Add(new TextItem(ReadItem(r)));
                    r.Skip();
                }
                continue;
            Label_00BA:
                Params.Add(ReadItem(r));
                r.Skip();
                continue;
            Label_00D3:
                r.Read();
                continue;
            Label_00DC:
                r.Skip();
            }
            r.Close();
        }

        public static void RebuildIndex()
        {
            if (!PauseRefresh)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.DoWork += new DoWorkEventHandler(AutoCompleteManager.bw_DoWork);
                worker.RunWorkerAsync();
            }
        }

        public static void ReturnMainIndex()
        {
            currentIndex = index;
            SearchOn = true;
            istack.PopAll();
            itstack.PopAll();
            sstack.PopAll();
        }

        private static void Save()
        {
            XmlTextWriter writer = new XmlTextWriter(new StreamWriter(Path.GetDirectoryName(Application.ExecutablePath) + @"\AutoComplete.xml", false, Encoding.UTF8));
            writer.WriteStartElement("Items");
            foreach (TextItem item in history)
            {
                writer.WriteStartElement("Item");
                writer.WriteAttributeString("Value", item.Text);
                writer.WriteEndElement();
            }
            foreach (string str in Params)
            {
                writer.WriteStartElement("Param");
                writer.WriteAttributeString("Value", str);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.Flush();
            writer.Close();
        }

        public static void SaveIgnoredFileExtensions()
        {
            try
            {
                FileStream stream = new FileStream("FileExtensionsToIgnore.txt", FileMode.OpenOrCreate, FileAccess.Write);
                StreamWriter writer = new StreamWriter(stream);
                foreach (string str in FileExtensionsToIgnore)
                {
                    writer.WriteLine(str.ToLower());
                }
                writer.Flush();
                writer.Close();
                stream.Close();
            }
            catch
            {
            }
        }

        public static void SavePriorities()
        {
            PushPriorities();
            try
            {
                FileStream stream = new FileStream("PersistData.dat", FileMode.Create, FileAccess.Write);
                StreamWriter writer = new StreamWriter(stream);
                foreach (int num in PriorityHash.Keys)
                {
                    writer.WriteLine(num.ToString() + "," + PriorityHash[num].ToString());
                }
                writer.Flush();
                writer.Close();
                stream.Close();
            }
            catch
            {
            }
        }

        public static bool SetSubIndex(IItem item, string itemtext, IAction action)
        {
            List<IItemContainer> list = new List<IItemContainer>();
            bool searchOn = true;
            foreach (ISubIndex index in PluginManager.SubIndexes)
            {
                if (!(item.ItemType.ToLower() == index.ParentItemType.ToLower()))
                {
                    continue;
                }
                List<IItemContainer> collection = new List<IItemContainer>();
                foreach (IItem item2 in index.GetSubIndex(item, action))
                {
                    collection.Add(new IItemContainer(item2));
                }
                list.AddRange(collection);
                searchOn = index.EnableSearch;
            }
            if (list.Count > 0)
            {
                SearchOn = searchOn;
                currentIndex = list;
                istack.Push(list, searchOn);
                itstack.Push(item);
                sstack.Push(itemtext);
                return true;
            }
            return false;
        }

        private static bool ShouldAdd(string file)
        {
            try
            {
                if (FileExtensionsToIgnore.Contains(Path.GetExtension(file).ToLower()))
                {
                    return false;
                }
                if (Path.GetFileName(file).StartsWith("~"))
                {
                    return false;
                }
                return true;
            }
            catch
            {
                return true;
            }
        }

        public static void SortIndex()
        {
            cachedIndexResults.Clear();
            cachedIndexResultIndices.Clear();
            index.Sort();
        }

        public static bool IsMainIndex
        {
            get
            {
                return (currentIndex == index);
            }
        }

        public static int MaximumResults
        {
            get
            {
                return MATCHLIM;
            }
            set
            {
                MATCHLIM = value;
            }
        }

        public static IItem ParentItem
        {
            get
            {
                return itstack.Top;
            }
        }

        public static string ParentText
        {
            get
            {
                return sstack.Top;
            }
        }

        public static bool SmartSearch
        {
            get
            {
                return SMARTSEARCH;
            }
            set
            {
                SMARTSEARCH = value;
            }
        }
    }
}

